/* Copyright 2009
 *
 * This program and the accompanying materials
 * are made available under the terms of the
 * Eclipse Public License v1.0 which accompanies
 * this distribution, and is available at
 *
 * 		http://www.eclipse.org/legal/epl-v10.html
 *
 * Unless required by applicable law or agreed to in
 * writing, software distributed under the License is
 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
 * OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing
 * permissions and limitations under the License.
 *
 * Contributors:
 * 	   IBM Corporation - initial API and implementation for JDT/DLTK
 *     Sean W. Quinn - initial adoption for use with PHP from various sources.
 */
package org.eclipse.php.internal.ui.preferences.formatter.tab;

import java.net.URL;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.dltk.internal.ui.util.SWTUtil;
import org.eclipse.dltk.ui.formatter.IFormatterModifyDialog;
import org.eclipse.dltk.ui.util.SWTFactory;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.php.internal.ui.preferences.formatter.Node;
import org.eclipse.php.internal.ui.preferences.formatter.PHPFormatterControlManager;
import org.eclipse.php.internal.ui.preferences.formatter.PHPFormatterMessages;
import org.eclipse.php.internal.ui.preferences.formatter.SnippetPreview;
import org.eclipse.php.internal.ui.widgets.PHPElementComponent;
import org.eclipse.php.internal.ui.widgets.SwitchComponent;
import org.eclipse.php.internal.ui.widgets.SyntaxComponent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.ui.dialogs.ContainerCheckedTreeViewer;
import org.eclipse.ui.part.PageBook;

/**
 * @author Sean W. Quinn (swquinn@gmail.com)
 */
@SuppressWarnings("restriction")
public class PHPCodeFormatterWhiteSpaceTabPage extends PHPCodeFormatterTabPage {

	//	private final class PHPElementComponent {
	//
	//	}

	private final class PHPSyntaxComponent extends SyntaxComponent {

		/**
		 * {@inheritDoc}
		 */
		public PHPSyntaxComponent(final Map workingValues) {
			super(workingValues);
		}

		@Override
		public void checkStateChanged(CheckStateChangedEvent event) {
			final Node node = (Node) event.getElement();
			node.setChecked(event.getChecked());
			doUpdatePreview();
			notifyValuesModified();
		}

		/**
		 * {@inheritDoc}
		 */
		public void createContents(final int numColumns, final Composite parent) {
			composite = new Composite(parent, SWT.NONE);
			composite.setLayoutData(createGridData(numColumns, GridData.HORIZONTAL_ALIGN_FILL, SWT.DEFAULT));
			composite.setLayout(createGridLayout(numColumns, false));

			createLabel(numColumns, composite, PHPFormatterMessages.WhiteSpaceTabPage_insert_space);
			treeViewer = new ContainerCheckedTreeViewer(composite, SWT.SINGLE | SWT.BORDER | SWT.V_SCROLL);
			treeViewer.setContentProvider(new ITreeContentProvider() {
				public Object[] getElements(Object inputElement) {
					return ((Collection) inputElement).toArray();
				}

				public Object[] getChildren(Object parentElement) {
					return ((Node) parentElement).getChildren().toArray();
				}

				public Object getParent(Object element) {
					return ((Node) element).getParent();
				}

				public boolean hasChildren(Object element) {
					return ((Node) element).hasChildren();
				}

				public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {}

				public void dispose() {}
			});
			treeViewer.setLabelProvider(new LabelProvider());
			treeViewer.getControl().setLayoutData(
					createGridData(numColumns, GridData.FILL_HORIZONTAL | GridData.FILL_VERTICAL, SWT.DEFAULT));
			//fDefaultFocusManager.add(fTreeViewer.getControl());
		}

		@Override
		public void refreshState() {
			super.refreshState();
			preview.clear();
			if (fLastSelected != null) {
				preview.addAll(fLastSelected.getSnippets());
			}
			doUpdatePreview();
		}

		@Override
		public void restoreSelection() {
			int index;
			try {
				index = dialogSettings.getInt(PREF_NODE_KEY);
			}
			catch (NumberFormatException ex) {
				index = -1;
			}
			if (index < 0 || index > fIndexedNodeList.size() - 1) {
				index = 0;
			}
			final Node node = (Node) fIndexedNodeList.get(index);
			if (node != null) {
				treeViewer.expandToLevel(node, 0);
				treeViewer.setSelection(new StructuredSelection(new Node[] { node }));
				fLastSelected = node;
			}
		}

		@Override
		public void selectionChanged(SelectionChangedEvent event) {
			final IStructuredSelection selection = (IStructuredSelection) event.getSelection();
			if (selection.isEmpty())
				return;
			final Node node = (Node) selection.getFirstElement();
			if (node == fLastSelected)
				return;
			dialogSettings.put(PREF_NODE_KEY, node.index);
			preview.clear();
			preview.addAll(node.getSnippets());
			doUpdatePreview();
			fLastSelected = node;
		}

	}

	/**
	 * @author Sean W. Quinn (swquinn@gmail.com)
	 */
	private final class PHPSwitchComponent extends SwitchComponent {
		private final String[] fItems = new String[] { PHPFormatterMessages.WhiteSpaceTabPage_sort_by_php_element,
				PHPFormatterMessages.WhiteSpaceTabPage_sort_by_syntax_element };

		public PHPSwitchComponent() {
			super(new PHPSyntaxComponent(new HashMap()), new PHPElementComponent());
		}

		@Override
		public void widgetSelected(SelectionEvent e) {
			final int index = getSwitchCombo().getSelectionIndex();
			final PHPElementComponent phpElementComponent = (PHPElementComponent) getElementComponent();
			final PHPSyntaxComponent phpSyntaxComponent = (PHPSyntaxComponent) getSyntaxComponent();

			if (index == 0) {
				dialogSettings.put(PREF_VIEW_KEY, false);
				phpElementComponent.refreshState();
				getPageBook().showPage(phpElementComponent.getControl());
			}
			else if (index == 1) {
				dialogSettings.put(PREF_VIEW_KEY, true);
				phpSyntaxComponent.refreshState();
				getPageBook().showPage(phpSyntaxComponent.getControl());
			}
		}

		@Override
		public void createContents(final int numColumns, final Composite parent) {
			final PHPElementComponent phpElementComponent = (PHPElementComponent) getElementComponent();
			final PHPSyntaxComponent phpSyntaxComponent = (PHPSyntaxComponent) getSyntaxComponent();

			PageBook pageBook = new PageBook(parent, SWT.NONE);
			pageBook.setLayoutData(createGridData(numColumns, GridData.FILL_BOTH, SWT.DEFAULT));

			phpElementComponent.createContents(numColumns, pageBook);
			phpSyntaxComponent.createContents(numColumns, pageBook);

			Combo switchCombo = new Combo(parent, SWT.READ_ONLY);
			SWTUtil.setDefaultVisibleItemCount(switchCombo);
			final GridData gd = createGridData(numColumns, GridData.HORIZONTAL_ALIGN_END, SWT.DEFAULT);
			switchCombo.setLayoutData(gd);
			switchCombo.setItems(fItems);

			this.setPageBook(pageBook);
			this.setSwitchCombo(switchCombo);
		}

		@Override
		protected void restoreSelection() {
			final PHPElementComponent phpElementComponent = (PHPElementComponent) getElementComponent();
			final PHPSyntaxComponent phpSyntaxComponent = (PHPSyntaxComponent) getSyntaxComponent();
			final boolean selectSyntax = dialogSettings.getBoolean(PREF_VIEW_KEY);

			if (selectSyntax) {
				phpSyntaxComponent.refreshState();
				getSwitchCombo().setText(fItems[1]);
				getPageBook().showPage(phpSyntaxComponent.getControl());
			}
			else {
				phpElementComponent.refreshState();
				getSwitchCombo().setText(fItems[0]);
				getPageBook().showPage(phpElementComponent.getControl());
			}
		}
	}

	private final SwitchComponent switchComponent;
	protected SnippetPreview preview;

	/**
	 * @param dialog
	 */
	public PHPCodeFormatterWhiteSpaceTabPage(final IFormatterModifyDialog dialog) {
		this(dialog, new HashMap());
	}

	/**
	 * @param dialog
	 */
	public PHPCodeFormatterWhiteSpaceTabPage(final IFormatterModifyDialog dialog, final Map workingValues) {
		super(dialog, workingValues);
		switchComponent = new PHPSwitchComponent();
	}

	/**
	 * @param manager
	 * @param parent
	 */
	@Override
	protected void doCreateOptions(final PHPFormatterControlManager manager, final Composite parent) {
		// **
		//
		final Group group = SWTFactory.createGroup(parent,
				PHPFormatterMessages.BracesTabPage_group_brace_positions_title, 4, 1, GridData.FILL_HORIZONTAL);
	}

	protected void doCreatePreferences(Composite composite, int numColumns) {
		switchComponent.createContents(numColumns, composite);
	}

	/**
	 *
	 */
	protected void initializePage() {
        switchComponent.initialize();
	}

	/**
	 *
	 */
    @Override
	protected void doUpdatePreview() {
    	super.updatePreview();
    	super.doUpdatePreview();
        preview.update();
    }

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected URL getPreviewContent() {
		return getClass().getResource("bracesPreview.php"); //$NON-NLS-1$
	}
}
